/*******************************************************************
 * Copyright (c) 2013 珠海比特讯科技有限公司. All rights reserved.
 * （1）软件的版权将受到法律保护，不允许非经授权的使用；
 * （2）未经版权所有人授权，任何人不得修改、复制和传播软件源代码、图片及其它资源等；
 * （3）未经版权所有人授权，不允许对软件进行修改；
 * （4）未经版权所有人授权，不允许在该软件的基础上开发新的软件；
 * （5）珠海比特讯科技有限公司拥有最终解释权
 *******************************************************************/
package youxiao.bytezon.controllers;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;

import youxiao.bytezon.models.GradeSubject;
import youxiao.bytezon.models.Subject;
import youxiao.bytezon.models.Teacher;
import youxiao.bytezon.params.teachers.ChangePasswordParam;
import youxiao.bytezon.params.teachers.EditProfileParam;
import youxiao.bytezon.repositories.TeacherRepository;
import youxiao.bytezon.views.commons.BaseRespView;
import youxiao.bytezon.views.teachers.TeacherView;

@RestController
@RequestMapping("/teachers")
public class TeachersController extends BaseController {

	@Autowired TeacherRepository teacherRepository;

	@Autowired
	EntityManager entityManager;

	@ResponseBody
	@RequestMapping(value = "/myinfo", method = RequestMethod.GET)
	public TeacherView myinfo(HttpServletRequest request) {
		Teacher currentTeacher = getCurrentTeacher();
		TeacherView teacherView = new TeacherView(currentTeacher);
		
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		
		CriteriaQuery<Subject> cq = cb.createQuery(Subject.class);
    Root<Subject> subject = cq.from(Subject.class);
    Join<Subject, GradeSubject> gradeSubjectsJoin = subject.join("gradeSubjects");
    
    cq.select(subject)
    		.where(
    			cb.and(
    				cb.equal(gradeSubjectsJoin.get("teacher"), currentTeacher)
    			)
    		).distinct(true);
    List<Subject> subjectList = entityManager.createQuery(cq).getResultList();
    teacherView.setSubjects(FluentIterable.from(subjectList).transform(new Function<Subject, String>() {
			public String apply(Subject subject) {
				return subject.getName();
			}
		}).toSet());

		return teacherView;
	}
	
	@ResponseBody
	@RequestMapping(value = "/profile", method = RequestMethod.PUT)
	public BaseRespView profile(@RequestBody @Validated EditProfileParam param, BindingResult bindingResult) {
		BaseRespView baseRespView = new BaseRespView();
		if (bindingResult.getFieldErrors().size() > 0) {
			baseRespView.setSuccess(false);
			return baseRespView;
		}
		
		Teacher currentTeacher = getCurrentTeacher();
		currentTeacher.setEmail(param.getEmail());
		teacherRepository.save(currentTeacher);

		return baseRespView;
	}
	
	@ResponseBody
	@RequestMapping(value = "/password", method = RequestMethod.PATCH)
	public BaseRespView password(@RequestBody @Validated ChangePasswordParam param, BindingResult bindingResult) {
		BaseRespView baseRespView = new BaseRespView();
		if (bindingResult.getFieldErrors().size() > 0) {
			baseRespView.setSuccess(false);
			return baseRespView;
		}
		
		Teacher currentTeacher = getCurrentTeacher();
		PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
		if (!passwordEncoder.matches(param.getOldPassword(), currentTeacher.getPassword())) {
			baseRespView.setSuccess(false);
			return baseRespView;
		}
		
		currentTeacher.setPassword(passwordEncoder.encode(param.getNewPassword()));
		teacherRepository.save(currentTeacher);

		return baseRespView;
	}
	
	@ResponseBody
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public TeacherView detail(@PathVariable("id") Long id) {
		Teacher teacher = teacherRepository.findOne(id);
		TeacherView teacherView = new TeacherView(teacher);

		return teacherView;
	}

}
